package com.action.utils;


import com.blankj.utilcode.util.StringUtils;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

public class DateTimeTool {
    static String dateFormat = "yyyy-MM-dd";
    static SimpleDateFormat format = new SimpleDateFormat(dateFormat);

    /**
     * String类型按格式转化成Date类型
     *
     * @param pattern
     * @param date
     * @return
     * @version 2011-8-31 上午10:54:47
     */
    public static Date dateFormat(String pattern, String date) {
        if (StringUtils.isEmpty(date))
            return null;
        try {
            if (pattern == null || pattern.equals("")) {
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date);
            } else {
                return new SimpleDateFormat(pattern).parse(date);
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return new Date();
    }

    /**
     * Date类型按格式转化成String类型
     *
     * @param pattern
     * @param date
     * @return
     * @version 2011-8-31 上午10:54:47
     */
    public static String dateFormat(String pattern, Date date) {
        if (date == null) {
            return "";
        }
        if (pattern == null || pattern.equals("")) {
            return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);
        } else {
            return new SimpleDateFormat(pattern).format(date);
        }
    }

    /**
     * 获取昨天的日期
     *
     * @return
     * @version 2011-9-22 下午05:43:48
     */
    public static String getDateByYesterDay() {
        String date = DateTimeTool.dateFormat("yyyy-MM-dd", new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000));
        return date;
    }

    /**
     * 明天
     *
     * @return
     */
    public static String getDateByTomorrow() {
        String date = DateTimeTool.dateFormat("yyyy-MM-dd", new Date(System.currentTimeMillis() + 24 * 60 * 60 * 1000));
        return date;
    }

    /**
     * 返回两个时间的所差天数
     *
     * @param begin
     * @param end
     * @return
     */
    public static int timeDistace(String begin, String end) {
        long beg = dateFormat("yyyy-MM-dd", begin).getTime();
        long en = dateFormat("yyyy-MM-dd", end).getTime();
        return (int) (en - beg) / (24 * 60 * 60 * 1000);
    }

    /**
     * 获取本月的第一天
     *
     * @return
     * @version 2011-9-22 下午05:43:48
     */
    public static Date getDateByMonthFirst(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 获取本月最后一天
     *
     * @return
     */
    public static Date getDateByMonthLast(Date date) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        return calendar.getTime();
    }

    /**
     * 获取本月的第一天
     *
     * @return
     * @version 2011-9-22 下午05:43:48
     */
    public static Date getDateByMonthFirst(String month) {

        Calendar calendar = new GregorianCalendar();
        calendar.setTime(dateFormat("yyyy-MM", month));
        calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
        return calendar.getTime();
    }

    /**
     * 获取本月最后一天
     *
     * @return
     */
    public static Date getDateByMonthLast(String month) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(dateFormat("yyyy-MM", month));
        calendar.set(Calendar.DATE, calendar.getActualMaximum(Calendar.DATE));
        return calendar.getTime();
    }

    /**
     * 获取当前日期
     *
     * @return
     * @version 2011-9-22 下午05:43:48
     */
    public static String getDateByToday() {
        return DateTimeTool.dateFormat("yyyy-MM-dd", new Date());
    }

    public static String queryStartDate(String date) {
        StringBuffer sb = new StringBuffer();
        return sb.append(date).append(" ").append("00:00:00").toString();
    }

    public static String queryEndDate(String date) {
        StringBuffer sb = new StringBuffer();
        return sb.append(date).append(" ").append("23:59:59").toString();
    }

    /**
     * 日期类型转换 Date ->yyyy-MM-01 00:00:00
     *
     * @param date
     * @return
     */
    public static String doDateFormatStringBeginningOfyyyymmdd000000(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        String datetime = null;
        try {
            if (date == null) {
                datetime = null;
            } else {
                datetime = format.format(date);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datetime;
    }

    /**
     * 日期类型转换 Date ->yyyy-MM-yy 00:00:00
     *
     * @param date
     * @return
     */
    public static String doDateFormatStringEndingOfyyyymmdd235959(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        String datetime = null;
        try {
            if (date == null) {
                datetime = "";
            } else {
                datetime = format.format(date);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datetime;
    }

    /**
     * 日期类型转换 Date ->yyyy-MM-01 00:00:00
     *
     * @param date
     * @return
     */
    public static Date doDateFormatBeginningOfyyyymmdd000000(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date datetime = null;
        try {
            if (date == null) {
                datetime = null;
            } else {
                datetime = format2.parse(format.format(date));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datetime;
    }

    /**
     * 日期类型转换 Date ->yyyy-MM-01 00:00:00
     *
     * @param date
     * @return
     */
    public static Date doDateFormatEndingOfyyyymmdd235959(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date datetime = null;
        try {
            if (date == null) {
                datetime = null;
            } else {
                datetime = format2.parse(format.format(date));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datetime;
    }

    /**
     * 是否在时间段内
     *
     * @param status
     * @param end
     * @return
     */
    public static boolean timecheck(Integer status, Integer end) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        if (hour >= status && hour < end) {
            return true;
        }
        return false;
    }

    /**
     * 提前10天
     */
    public static String ticketOrderTime(Date now) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        long l = now.getTime() + 9 * 24 * 60 * 60 * 1000;
        now.setTime(l);
        return sdf.format(now);

    }

    /**
     * 日期类型转换 Date ->String
     *
     * @param date
     * @return
     */
    public static String doDateFormatString(Date date) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String datetime = null;
        try {
            if (date == null) {
                datetime = "";
            } else {
                datetime = format.format(date);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return datetime;
    }

    /**
     * N秒之前
     *
     * @param n
     * @param date
     * @return
     */
    public static Date nSecondAgo(Integer n, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.SECOND, cal.get(Calendar.SECOND) + n);
        return cal.getTime();
    }

    /**
     * N分钟之前
     *
     * @param n
     * @param date
     * @return
     */
    public static Date nMinuteAgo(Integer n, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MINUTE, cal.get(Calendar.MINUTE) + n);
        return cal.getTime();
    }

    /**
     * N天之前
     *
     * @param n
     * @param date
     * @return
     */
    public static Date nDaysAgo(Integer n, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DAY_OF_MONTH, cal.get(Calendar.DAY_OF_MONTH) + n);
        return cal.getTime();
    }

    /**
     * N月之前
     *
     * @param n
     * @param date
     * @return
     */
    public static Date nMonthsAgo(Integer n, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + n);
        return cal.getTime();
    }

    /**
     * N年之前
     *
     * @param n
     * @param date
     * @return
     */
    public static Date nYearsAgo(Integer n, Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.YEAR, cal.get(Calendar.YEAR) + n);
        return cal.getTime();
    }

    /**
     * 是否同一天
     *
     * @return
     */
    public static Boolean isSameDay(String pattern, Date date1, Date date2) {
        SimpleDateFormat format = null;
        if (!StringUtils.isEmpty(pattern)) {
            format = new SimpleDateFormat(pattern);
        } else {
            format = new SimpleDateFormat("yyyy-MM-dd");
        }
        try {
            date1 = format.parse(format.format(date1));
            date2 = format.parse(format.format(date2));
            if (date1.compareTo(date2) == 0) {
                return true;
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return false;
    }

    public static int getYear(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        return cld.get(Calendar.YEAR);
    }

    public static int getMonth(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        return cld.get(Calendar.MONTH) + 1;
    }

    public static int getDay(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        return cld.get(Calendar.DAY_OF_MONTH);
    }

    public static int getHour(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        return cld.get(Calendar.HOUR_OF_DAY);
    }

    public static int getMinute(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        return cld.get(Calendar.MINUTE);
    }

    public static int getSecond(Date date) {
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);
        return cld.get(Calendar.SECOND);
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date smdate, Date bdate) {
        int between_days = 0;
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            smdate = sdf.parse(sdf.format(smdate));
            bdate = sdf.parse(sdf.format(bdate));
            Calendar cal = Calendar.getInstance();
            cal.setTime(smdate);
            long time1 = cal.getTimeInMillis();
            cal.setTime(bdate);
            long time2 = cal.getTimeInMillis();

            between_days = Integer.parseInt(String.valueOf((time2 - time1) / (1000 * 3600 * 24)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return between_days;
    }

    /**
     * 字符串的日期格式的计算
     */
    public static int daysBetween(String smdate, String bdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.setTime(sdf.parse(smdate));
        long time1 = cal.getTimeInMillis();
        cal.setTime(sdf.parse(bdate));
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 两个时间相差几秒
     *
     * @param startDate
     * @return
     */
    public static int calLastedTime(Date startDate) {
        long a = new Date().getTime();
        long b = startDate.getTime();
        int c = (int) ((a - b) / 1000);
        return c;
    }

    /**
     * 计算两个时间的秒数
     * @param startDate
     * @param endDate
     * @return
     */
    public static int calSecondsDurTwoTime(Date startDate,Date endDate){
        long a = endDate.getTime();
        long b = startDate.getTime();
        int c = (int) ((a - b) / 1000);
        return c;
    }
    public static Date getToday24Hour(){
        Date date=new Date();
        date.setHours(23);
        date.setMinutes(59);
        date.setSeconds(59);
        return date;
    }
    /**
     * 将String转化成Timestamp
     * ld 20160727
     *
     * @param tsStr
     * @return
     */
    public static Timestamp dateFormat(String tsStr) {
        Timestamp ts = new Timestamp(System.currentTimeMillis());
        try {
            ts = Timestamp.valueOf(tsStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ts;
    }

    /**
     * 查出String类型之间 时间间隔的所有日期
     * ld 20170213
     *
     * @param date1
     * @param date2
     * @return
     */
    public static List<String> process(String date1, String date2) {
        if (date1.equals(date2)) {
            System.out.println("两个日期相等!");
            return null;
        }

        String tmp;
        if (date1.compareTo(date2) > 0) {  //确保 date1的日期不晚于date2
            tmp = date1;
            date1 = date2;
            date2 = tmp;
        }

        tmp = format.format(str2Date(date1).getTime() + 3600 * 24 * 1000);

        int num = 0;
        List<String> list = new ArrayList<String>();
        while (tmp.compareTo(date2) < 0) {
            list.add(tmp);
            System.out.println(tmp);
            num++;
            tmp = format.format(str2Date(tmp).getTime() + 3600 * 24 * 1000);
        }

        if (num == 0) {
            System.out.println("两个日期相邻!");
        }
        return list;
    }

    public static Date str2Date(String str) {
        if (str == null) return null;
        try {
            return format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static final int SECONDS_PER_MINUTE = 60;
    private static final int MINUTES_PER_HOUR = 60;
    private static final int HOURS_PER_DAY = 24;
    private static final int SECONDS_PER_DAY = (HOURS_PER_DAY * MINUTES_PER_HOUR * SECONDS_PER_MINUTE);
    /**
     * 一天的毫秒数
     **/
    private static final long DAY_MILLISECONDS = SECONDS_PER_DAY * 1000L;

    /**
     * excel导入加新的日期
     * woody 20180301
     *
     * @param numberString 天数
     * @return
     */
    public static Date excelDateFormate(double numberString) {
        int wholeDays = (int) Math.floor(numberString);
        int millisecondsInday = (int) ((numberString - wholeDays) * DAY_MILLISECONDS + 0.5);
        Calendar calendar = new GregorianCalendar();
        int startYear = 1900;
        int dayAdjust = -1; // Excel thinks 2/29/1900 is a valid date, which it isn't
        if (wholeDays < 61) {
            // Date is prior to 3/1/1900, so adjust because Excel thinks 2/29/1900 exists
            // If Excel date == 2/29/1900, will become 3/1/1900 in Java representation
            dayAdjust = 0;
        }
        calendar.set(startYear, 0, wholeDays + dayAdjust, 0, 0, 0);
        calendar.set(GregorianCalendar.MILLISECOND, millisecondsInday);
        return calendar.getTime();
    }

    public static void main(String[] args) throws ParseException {

        System.out.println(DateTimeTool.isSameDay("yyyy-MM", new Date(), DateTimeTool.nDaysAgo(5, new Date())));
        System.out.println(DateTimeTool.dateFormat("", DateTimeTool.nYearsAgo(3, new Date())));
        System.out.println(DateTimeTool.getDateByMonthFirst(new Date()));
        System.out.println(DateTimeTool.getDateByMonthLast(new Date()));
        System.out.println(DateTimeTool.getDay(new Date()));
        Date date = new Date();
        System.out.println(date);
        System.out.println(DateTimeTool.nSecondAgo(2, date));
        System.out.println(dateFormat("yyMMddHHmmss", new Date()));
        System.out.println(DateTimeTool.queryStartDate(DateTimeTool.dateFormat("yyyy-MM-dd", DateTimeTool.nDaysAgo(-1, new Date()))));
        System.out.println(DateTimeTool.queryEndDate(DateTimeTool.dateFormat("yyyy-MM-dd", DateTimeTool.nDaysAgo(-1, new Date()))));


        System.out.println(DateTimeTool.dateFormat("", "2014-04-25 13:00:01").after(DateTimeTool.dateFormat("", "2014-04-25 13:00:00")));

        System.out.println(DateTimeTool.dateFormat("", "2014-04-26 13:00:00").before(DateTimeTool.nDaysAgo(1, DateTimeTool.dateFormat("", "2014-04-25 14:00:00"))));
        System.out.println(getDateByMonthFirst("2014-04"));
        System.out.println(getDateByMonthLast("2014-04"));


        String month = DateTimeTool.dateFormat("yyyy-MM", new Date());
        System.out.println(DateTimeTool.dateFormat("", DateTimeTool.nMonthsAgo(1, DateTimeTool.getDateByMonthFirst(month))));
        System.out.println(DateTimeTool.getDay(new Date()));
        System.out.println(DateTimeTool.nDaysAgo(1, DateTimeTool.doDateFormatBeginningOfyyyymmdd000000(new Date())));
        Date dates = DateTimeTool.nDaysAgo(-1, DateTimeTool.nMonthsAgo(1, new Date()));
        System.out.println(dates);
        System.out.println(DateTimeTool.doDateFormatEndingOfyyyymmdd235959(dates));

        Date d1 = dateFormat("", "2014-11-18 18:41:10");
        Date d2 = dateFormat("", "2014-09-10 10:10:10");
        System.out.println(daysBetween(d1, d2));

        System.out.println(daysBetween("2012-09-08 10:10:10", "2012-09-15 00:00:00"));
        System.out.println(doDateFormatStringBeginningOfyyyymmdd000000(DateTimeTool.nDaysAgo(-1, new Date())));
        System.out.println(doDateFormatStringEndingOfyyyymmdd235959(new Date()));

        System.out.println(calLastedTime(d1));

        date = dateFormat("yyyy-MM-dd HH:mm", "2014-12-19 17:18");
        Calendar cld = Calendar.getInstance();
        cld.setTime(date);

        int currentYear = cld.get(Calendar.YEAR);
        int currentMonth = cld.get(Calendar.MONTH) + 1;
        int currentDay = cld.get(Calendar.DAY_OF_MONTH);
        int currentHour = cld.get(Calendar.HOUR_OF_DAY);
        int currentMinute = cld.get(Calendar.MINUTE);
        System.out.println(currentYear);
        System.out.println(currentMonth);
        System.out.println(currentDay);
        System.out.println(currentHour);
        System.out.println(currentMinute);
        System.out.println(excelDateFormate(42605l));

    }
}
